/*
    SEL - Simple DirectMedia Layer Extension Library
    Copyright (C) 2001, 2002 Matej Knopp <knopp@users.sf.net>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef __sel_animation_h__
#define __sel_animation_h__

#include <vector>
#include "object.h"

namespace SEL
{

class Surface;

/*
 * Animation abstraction
 */

//! Basic animation class.
class Animation : public Object
{
public:
	//! Animation frame (contains one surface).
	class Frame
	{
	public:
		//!
		Frame (Surface * surface = NULL, Uint32 duration = 0);
		
		//!
		~Frame ();
		
		//!
		void setSurface (Surface *);

		//!		
		void releaseSurface ();
		
		//!		
		Surface * surface ()			{ return m_surface; }
		
		//!
		const Surface * surface () const 	{ return m_surface; }
		
		//!
		void setDuration (Uint32 duration);
		
		//!
		Uint32 duration () const		{ return m_duration; }
	
		typedef std::vector <Frame> List;
	
		Frame & operator= (Frame & frame);
		
	protected:
		Surface *m_surface;
		Uint32 m_duration;
	};

	//!	
	Animation ();
	
	//!
	virtual ~Animation ();	

	/*
	 * FRAMES
	 */
	
	//!
	void addFrame (Frame & frame);
	
	//!
	void insertFrame (Frame & frame, int pos);

	//!
	void removeFrame (int index);
	
	//!
	void removeFrame (Frame &frame);

	//!
	Frame & operator [] (int idx)		  { return m_frames [idx]; }
	
	//!
	const Frame & operator [] (int idx) const { return m_frames [idx]; }

	//!
	int size () const			  { return m_frames.size (); }
	
	/*
	 * ORDER
	 */
	 
	//!
	enum OrderType
	{
		OrderForward = 0,
		OrderBackward,
		OrderPingPong
	};

	typedef std::vector <int> Order;
	 
	//!
	void generateOrder (OrderType type = OrderForward);
	
	//!
	void setOrder (const Order & order);
	
	//!
	Order & order () 			{ return m_order; }
	
	//!
	const Order & order () const		{ return m_order; }
	
	/*
	 * Playing
	 */
	
	//!
	void toBegin ();
	
	//!
	void toEnd ();

	//!
	void prev (bool loop = true);
	
	//!
	void next (bool loop = true);
	
	//!
	void go (unsigned int position);
	
	//!
	unsigned int position () const		{ return m_position; }
	
	//!
	Frame & currentFrame () 		{ return m_frames [m_order [m_position]]; }
	
	//!
	const Frame & currentFrame () const 	{ return m_frames [m_order [m_position]]; }

	//!
	int loopCount () const			{ return m_loop_count; }
	
	//!
	void setLoopCount (int loop_count = -1);
	
protected:
	Frame::List m_frames;
	Order m_order;
	int m_loop_count;
	unsigned int m_position;
};

}; // namespace SEL

#endif // __sel_animation_h__
